package com.et.mserver;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoEventType;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.concurrent.ThreadPoolExecutor;

public class MServer {

	// 消息处理线程池大小上限
	private static final int handleThreadCount = 256;

	// server's port
	private static final int port = 9998;

	public static void main(final String[] args) throws IOException {

		MDC.put("ServerAddress", InetAddress.getLocalHost().toString());
		MDC.put("product", "fs");

		final NioSocketAcceptor acceptor;

		acceptor = new NioSocketAcceptor();
		acceptor.setReuseAddress(true);
		acceptor.setCloseOnDeactivation(true);

		final SocketSessionConfig socketConfig = acceptor.getSessionConfig();
		socketConfig.setReuseAddress(true);
		socketConfig.setReceiveBufferSize(16 * 1024);
		socketConfig.setSendBufferSize(16 * 1024);
		socketConfig.setReadBufferSize(16 * 1024);

		//设置I/O处理层
		final DefaultIoFilterChainBuilder filterChainBuilder = acceptor.getFilterChain();

		// 加入编解码Filter
		filterChainBuilder.addLast("codec", new ProtocolCodecFilter(new PrefixedXMLStreamCodecFactory()));

		// 加入业务处理线程池Filter
		final ThreadPoolExecutor serverOrderedExeutor;

		// if handleThreadCount > 1
		serverOrderedExeutor = new MailOrderedThreadPoolExecutor(handleThreadCount / 2, handleThreadCount);
		//serverOrderedExeutor = new OrderedThreadPoolExecutor(handleThreadCount / 2, handleThreadCount);

		// if handleTreadCount == 1
//			serverOrderedExeutor = new MailOrderedThreadPoolExecutor(
//					1, handleThreadCount);

		filterChainBuilder.addLast("threadpool", new ExecutorFilter(serverOrderedExeutor, IoEventType.MESSAGE_RECEIVED, IoEventType.SESSION_CLOSED));

		final MIOHandler myIOHandler = new MIOHandler();
		acceptor.setHandler(myIOHandler);

		acceptor.getSessionConfig().setIdleTime(IdleStatus.READER_IDLE, 30);
		acceptor.getSessionConfig().setWriteTimeout(60);

		acceptor.bind(new InetSocketAddress(port));

		final StringBuilder sb = new StringBuilder("server start at port: ");
		sb.append(port);

		if (logger.isInfoEnabled()) {
			logger.info(sb.toString());
		}
	}

	private static Logger logger = LoggerFactory.getLogger(MServer.class);

}
